// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

part of dart.core;

/**
 * 所有函数类型的基类。
 *
 * 一个函数值，或实现了"call"方法的类的实例，是函数类型[Function]的子类型。
 */
abstract class Function {
  /**
   * 用指定的参数动态调用[function]。
   *
   * 和使用[positionalArguments]的元素作为对应的位置参数，
   * 使用[namedArguments]的元素作为对应的命名参数参数，来调用`function`作用相同。
   *
   * 如果[function]是不可调用的，或要求不同的参数，会抛出相同的错误。
   *
   * 例子:
   *       Map<Symbol, dynamic> namedArguments = new Map<Symbol, dynamic>();
   *       namedArguments[const Symbol("f")] = 4;
   *       namedArguments[const Symbol("g")] = 5;
   *       Function.apply(foo, [1,2,3], namedArguments);
   *
   * 与下面表达式的结果完全相同：
   *       foo(1, 2, 3, f: 4, g: 5).
   *
   * 如果[positionalArguments]为null，它会被认为是一个空的List。
   * 如果[namedArguments]未设置或为null，它会被认为是一个空的Map。
   */
  external static apply(Function function,
                        List positionalArguments,
                        [Map<Symbol, dynamic> namedArguments]);

  /**
   * 返回一个与`operator==`操作兼容的哈希值。
   */
  int get hashCode;

  /**
   * 测试`this`函数对象与另一个对象是否相等。
   *
   * 系统创建的函数对象仅和其它函数相等。
   *
   * 以下情况，两个函数对象被视为表示相同函数：
   * - 相同对象。当静态和顶层函数作为值的时候，是编译时常量。
   *   所以如果引用相同函数两次，调用的依旧是相同对象。
   * - 或者，如果它们引用提取自相同对象的同一个成员方法。
   *   提取成员方法作为函数值两次，函数值相等，但是`identical`不一定为`true`。
   *
   * 例子：
   *     class A {
   *       foo() => null;
   *     }
   *
   *     void main()
   *     {
   *       A a = new A();
   *       Function f1 = a.foo;
   *       Function f2 = a.foo;
   *
   *       print(f1 == f2);
   *       print(identical(f1, f2));
   *     }
   *
   * 函数表达式绝不会产生相同的函数对象。每次对函数表达式求值时，会创建一个新的闭包值，
   * 与相同表达式创建的另一个闭包值不相等。
   *
   * 类通过实现`call`方法来实现`Function`时，
   * 应该根据对象的不同，重写`operator==`和`hashCode`。
   */
  bool operator==(Object other);
}
